package cn.com.joycode.nimble.opencv.test.javacv;

import cn.com.joycode.nimble.opencv.JavaCvUtil;
import cn.com.joycode.nimble.opencv.test.BaseTest;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.javacv.CanvasFrame;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.OpenCVFrameGrabber;
import org.bytedeco.opencv.global.opencv_core;
import org.bytedeco.opencv.global.opencv_imgproc;
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_core.Scalar;
import org.bytedeco.opencv.opencv_core.Size;
import org.bytedeco.opencv.opencv_videoio.VideoCapture;
import org.junit.jupiter.api.Test;
import org.opencv.core.CvType;
import org.opencv.videoio.Videoio;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;

@Slf4j
public class JavaCvCamera extends BaseTest {

    @Data
    public static class MatPanel extends JPanel {

        private Mat mat;

        public MatPanel(Mat mat) {
            this.mat = mat;
        }

        @Override
        public void paint(Graphics g) {
            BufferedImage bufferedImage = JavaCvUtil.matToBufferedImage(mat.clone());
            g.drawImage(bufferedImage, 0, 0, this);
        }
    }


    @Test
    public void camara() throws Exception {
        OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
        grabber.start();   //开始获取摄像头数据
        CanvasFrame canvas = new CanvasFrame("摄像头");//新建一个窗口
        canvas.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        canvas.setAlwaysOnTop(true);
        while (true) {
            if (!canvas.isDisplayable()) {//窗口是否关闭
                grabber.stop();//停止抓取
                System.exit(-1);//退出
            }

            Frame frame = grabber.grab();
            canvas.showImage(frame);//获取摄像头图像并放到窗口上显示， 这里的Frame frame=grabber.grab(); frame是一帧视频图像
            Thread.sleep(100);//50毫秒刷新一次图像
        }
    }

    @Test
    public void videoCam() throws Exception {
        VideoCapture camera = new VideoCapture(0);
        camera.set(Videoio.CAP_PROP_FRAME_WIDTH, 960);
        camera.set(Videoio.CAP_PROP_FRAME_HEIGHT, 540);
        Mat mat = new Mat(new Size(960, 540), CvType.CV_8UC3, new Scalar(0, 0, 0, 0));
        MatPanel t = new MatPanel(mat);
        JFrame frame = new JFrame();
        frame.getContentPane().add(t);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setSize(800, 480);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        while (true) {

            if (camera.read(mat)) {
                Mat result = new Mat();
                //opencv_imgproc.cvtColor(mat, result, opencv_imgproc.CV_BGR2GRAY);
                //opencv_imgproc.cvtColor(result, mat, opencv_imgproc.CV_GRAY2BGR);
                //opencv_core.bitwise_not(mat, mat);
                //opencv_imgproc.cvtColor(mat, result, opencv_imgproc.CV_RGB2BGR);

                opencv_imgproc.cvtColor(mat, result, opencv_imgproc.COLOR_BGR2GRAY);
                opencv_imgproc.Canny(result, result, 50, 250, 5, true);

                opencv_imgproc.cvtColor(result, mat, opencv_imgproc.CV_GRAY2BGR);
                opencv_core.bitwise_not(mat, mat);
                t.repaint();
            }

        }
    }


    public static void main(String[] args) {
        VideoCapture camera = new VideoCapture(0);
        camera.set(Videoio.CAP_PROP_FRAME_WIDTH, 960);
        camera.set(Videoio.CAP_PROP_FRAME_HEIGHT, 540);
        Mat mat = new Mat();
        MatPanel t = new MatPanel(mat);
        JFrame frame = new JFrame();
        frame.getContentPane().add(t);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setSize(800, 480);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        while (true) {
            if (camera.read(mat)) {
                t.repaint();
            }
            try {
                Thread.sleep(200);
            } catch (Exception e) {
                log.error("异常", e);
            }
        }
    }
}
